package com.software.comment.service.impl;

import com.alibaba.excel.util.BooleanUtils;

import com.software.comment.mapper.LikeMapper;
import com.software.comment.pojo.Like;
import com.software.comment.service.LikeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author 周昊
 * @since 2024/12/16 11：34
 * @version 1.0
 */
@Service
public class LikeServiceImpl implements LikeService {

    // 缓存时间
    private static final long CACHE_EXPIRATION = 60L;
    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private LikeMapper likeMapper;

    /**
     * 展示评论点赞列表
     *
     * @param taskId 评论所在任务ID
     * @return 评论点赞列表
     */
    @Override
    public List<Like> showLikes(Integer taskId) {
        return likeMapper.selectLikeByCommentId(taskId);
    }

    /**
     * 点赞评论，放入Redis缓存
     *
     * @param username 执行点赞的用户名
     * @param commentId 评论ID
     */
    @Override
    public void addlike(String username, Integer commentId) {
        String key = "comment:liked:" + commentId;
        boolean isSuccess = likeMapper.insertLike(username, commentId);
        if (isSuccess) {
            redisTemplate.opsForSet().add(key, username);
            // 新增：获取当前点赞数并缓存到Redis
            getAndCacheLikeCount(commentId);
        }
    }

    /**
     * 评论的有无在数据库中的记录
     *
     * @param username 执行点赞的用户名
     * @param commentId 评论ID
     * @return 点赞数
     */
    @Override
    public Integer countByCommentId(Integer commentId, String username) {
        // 数据库没有记录
        int notLike =0 ;
        // 数据库有记录
        int hasLiked = 1;
        String key = "comment:liked:" + commentId;
        // 先尝试从Redis获取点赞数
        Boolean isMember = redisTemplate.opsForSet().isMember(key, username);
        // redis中显示点过赞
        if (BooleanUtils.isTrue(isMember)) {
            return hasLiked;
        }
        // 如果Redis中不存在，从数据库查询点赞
        Integer isLike = likeMapper.selectIsLike(commentId, username);
        // 数据库没有记录
        if (isLike == null) {
            return notLike;
        }
        // 未点赞，有记录
        if (isLike == 0) {
            return hasLiked;
        }
        // 点赞，有记录
        return hasLiked;
    }
    /**
     * 取消点赞，删除Redis缓存
     *
     * @param isLikedInDB 点赞状态，true表示已点赞，false表示未点赞
     * @param username    执行取消点赞的用户名
     * @param commentId   评论ID
     */
    @Override
    public void toChangeLike(Boolean isLikedInDB, String username, Integer commentId) {
        String key = "comment:liked:" + commentId;
        //判断是否在redis中有点赞记录
        Boolean isMember = redisTemplate.opsForSet().isMember(key, username);
        if (BooleanUtils.isFalse(isMember)) {
            boolean isSuccess = likeMapper.updateToLike(commentId, username);
            if (isSuccess) {
                redisTemplate.opsForSet().add(key, username);
                // 获取当前点赞数并缓存到Redis
                getAndCacheLikeCount(commentId);
            }
        } else {
            boolean isSuccess = likeMapper.updateToCancelLike(commentId, username);
            if (isSuccess) {
                redisTemplate.opsForSet().remove(key, username);
                // 获取当前点赞数并缓存到Redis
                getAndCacheLikeCount(commentId);
            }
        }
    }

    /**
     * 检查点赞状态，优先从Redis缓存中获取，如果没有则查询数据库
     *
     * @param commentId 评论ID
     * @param username 执行点赞的用户名
     * @return 1表示已点赞，0表示未点赞，null表示操作失败
     */
    @Override
    public Integer checkLike(Integer commentId, String username) {
        String key = "comment:liked:" + commentId;
        boolean isMember = Boolean.TRUE.equals(redisTemplate.opsForSet().isMember(key, username));
        if (BooleanUtils.isTrue(isMember)) {
            return 1;
        } else {
            Integer dbResult = likeMapper.selectIsLike(commentId, username);
            if (dbResult!= null && dbResult == 1) {
                redisTemplate.opsForSet().add(key, username);
                // 获取当前点赞数并缓存到Redis
                getAndCacheLikeCount(commentId);
            }
            // 返回数据库查询结果
            return 0;
        }
    }

    /**
     * 查询like状态
     *
     * @param commentId 评论id
     * @param username  点赞用户名
     * @return like状态结果
     */
    @Override
    public Integer selectLikeByCommentIdAndUsername(Integer commentId, String username) {
        return likeMapper.selectLikeByCommentIdAndUsername(commentId, username);
    }

    private void getAndCacheLikeCount(Integer commentId) {
        String countKey = "comment:like_count:" + commentId;
        // 先尝试从Redis获取点赞数
        String countStr = redisTemplate.opsForValue().get(countKey);
        if (countStr!= null) {
            return;
        }
        // 如果Redis中不存在，从数据库查询点赞数
        Integer likeCount = likeMapper.countByCommentId(commentId, null);
        if (likeCount!= null) {
            // 将点赞数缓存到Redis，并设置过期时间
            redisTemplate.opsForValue().set(countKey, likeCount.toString(), CACHE_EXPIRATION, TimeUnit.SECONDS);
        }
    }

}